/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
// Pro16scrn.hpp - Linear screen driver for 16-bpp (65K color) operation.
//
// Author: Kenneth G. Maxwell
//
// Copyright (c) 2006 Swell Software, Inc.
//              All Rights Reserved.
//
// Unauthorized redistribution of this source code, in whole or part,
// without the express written permission of Swell Software
// is strictly prohibited.
//
// Notes:
//
//  This screen driver is intended for use with 256-color systems that support
//  a linear frame buffer. Example controllers include the SMOS 135xx series
//  and the MPC823.
//
//
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

#ifndef _Pro16SCREEN_
#define _Pro16SCREEN_


/*--------------------------------------------------------------------------*/

#if (PEG_ORIENTATION == PEG_ORIENTATION_ROTATE_CCW)
  #define PlotPointView(x, y, c) *(SCANLINESTART(x) - y) = (PEGCOLOR) c;
#else
  #define PlotPointView(x, y, c) *(SCANLINESTART(x) + y) = (PEGCOLOR) c;
#endif

/*--------------------------------------------------------------------------*/
// Useful macros for dealing with 16-bit colors
/*--------------------------------------------------------------------------*/
#define REDVAL565(c)   (PEGUBYTE)(((c) & 0xf800) >> 8)
#define REDVAL555(c)   (PEGUBYTE)(((c) & 0x7c00) >> 7)
#define GREENVAL565(c) (PEGUBYTE)(((c) & 0x07e0) >> 3)
#define GREENVAL555(c) (PEGUBYTE)(((c) & 0x03e0) >> 2)
#define BLUEVAL565(c)  (PEGUBYTE)(((c) & 0x001f) << 3)
#define BLUEVAL555(c)  (PEGUBYTE)(((c) & 0x001f) << 3)
#if defined(PEG_BIG_ENDIAN)
#define MAKE565(r, g, b) ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
#define MAKE555(r, g, b) ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3))
#else
#define MAKE565(r, g, b) ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
#define MAKE555(r, g, b) ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3))
#endif

#ifdef PEG_RGB_USE_565
 #define REDVAL(c)   REDVAL565(c)
 #define GREENVAL(c) GREENVAL565(c)
 #define BLUEVAL(c)  BLUEVAL565(c)
 #define MAKEHICOLOR(r, g, b) MAKE565(r, g, b)
#else
 #define REDVAL(c) REDVAL555(c)
 #define GREENVAL(c) GREENVAL555(c)
 #define BLUEVAL(c) BLUEVAL555(c)
 #define MAKEHICOLOR(r, g, b) MAKE555(r, g, b)
#endif

#define REDVALCHECK(b, c)   IS_555(b) ? REDVAL555(c) : REDVAL565(c)
#define GREENVALCHECK(b, c) IS_555(b) ? GREENVAL555(c) : GREENVAL565(c)
#define BLUEVALCHECK(b, c)  IS_555(b) ? BLUEVAL555(c) : BLUEVAL565(c)

#define BLEND(c1, c2, a) (PEGUBYTE)((((c1) * (a)) + (((c2) * (256 - (a))))) >> 8)
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
class Pro16Screen : public PegScreen
{
    public:
        Pro16Screen(const PegRect &);
        virtual ~Pro16Screen();

        virtual void Capture(PegCapture *Info, PegRect &Rect);

        virtual PegBitmap *CreateBitmap(PEGINT Width, PEGINT Height,
            PEGINT Style = BMF_RAW|BMF_HAS_TRANS);

        virtual PEGUBYTE *GetPalette(PEGULONG *pPutSize);

       #ifdef PEG_IMAGE_SCALING

        virtual PEGCOLOR GetBitmapPixel(PEGINT x, PEGINT y, PegBitmap *pMap)
        {
            PEGCOLOR *pGet = (PEGCOLOR *) (pMap->pStart);
            if (mOrientation == PEG_ORIENTATION_ROTATE_CCW)
            {
                pGet += (pMap->Height * (x + 1)) - 1;
                pGet -= y;
            }
            else
            {            
                pGet += pMap->Height * x;
                pGet += y;
            }

            return *pGet;
        }

       #endif

        virtual PEGCOLOR GetPixelView(PEGINT x, PEGINT y)
        {
            if (mpContext)
            {
                if (mOrientation == PEG_ORIENTATION_ROTATE_CCW)
                {
                    return((PEGCOLOR) *(SCANLINESTART(x) - y));
                }
                else
                {
                    return((PEGCOLOR) *(SCANLINESTART(x) + y));
                }
            }
            else
            {
                return 0;
            }
        }

       #ifdef PEG_IMAGE_SCALING

        virtual void PutBitmapPixel(PEGINT x, PEGINT y, PegBitmap *pMap,
                                    PEGCOLOR Val)
        {
            PEGCOLOR *pPut = (PEGCOLOR *) (pMap->pStart);
            if (mOrientation == PEG_ORIENTATION_ROTATE_CCW)
            {
                pPut += (pMap->Height * (x + 1)) - 1;
                pPut -= y;
            }
            else
            {
                pPut += pMap->Height * x;
                pPut += y;
            }
            *pPut = Val;
        }

       #endif

        virtual void ResetPalette(void);
        virtual void SetPalette(PEGINT First, PEGINT Num,
                                const PEGUBYTE *pGet);

    protected:

       #ifdef PEG_AA_LINE
        virtual void AALineView(PEGINT xStart, PEGINT yStart, PEGINT xEnd,
                                PEGINT yEnd, const PegRect & View,
                                PegBrush &Brush);
       #endif

        virtual void BitmapView(const PegPoint Where,
                                const PegBitmap *pGetmap,
                                const PegRect &View);

       #if defined(PEG_MULT_SOFT_SURFACES)

        void BlendSurface(DrawSurface *pSurface, PegRect &Copy,
            PEGUBYTE *pComposite);

        PEGBOOL BuildCompositeSurface(PegRect &Copy, PEGUBYTE *pComposite);

        void CopySurface(DrawSurface *pSurface, PegRect &Copy,
            PEGUBYTE *pComposite);

       #endif

       #ifdef PEG_AA_FONT
        virtual void DrawSimpleAliasedText(PegPoint Where,
                        const PEGCHAR *pText, PegBrush &Brush,
                        const PegFont *pFont, PEGINT Count, PegRect &Rect);

       #if defined(PEG_PRO)

        virtual void DrawTrueAliasedText(PegPoint Where,
                        const PEGCHAR *pText, PegBrush &Brush,
                        const PegFont *pFont, PEGINT Count, PegRect &Rect);

        virtual void DrawAliasedTextToAlphaMap(PegPoint Where,
                        const PEGCHAR *pText, PegBrush &Brush,
                        const PegFont *pFont, PEGINT Count, PegRect &Rect);
       #endif
       #endif

       #ifdef PEG_PRO
        virtual void DrawAliasMapView(PegPoint Where, const PegBitmap *pMap,
            PegBrush &Brush, const PegRect &View);
       #endif

       #ifdef PEG_FREETYPE_SUPPORT
        virtual void DrawFreetypeAliasedText(PegPoint Where, const PEGCHAR *pText,
            PegBrush &Brush, const PegFont *pFont, PEGINT Count, PegRect &Clip);

        virtual void DrawFreetypeBinaryText(PegPoint Where, const PEGCHAR *pText,
            PegBrush &Brush, const PegFont *pFont, PEGINT Count, PegRect &Clip);
       #endif

       #ifdef PEG_OUTLINE_FONT
        virtual void DrawOutlineText(PegPoint Where, const PEGCHAR *pText,
                                     PegBrush &Brush, const PegFont *pFont,
                                     PEGINT Count, PegRect &Rect);
       #endif

        virtual void DrawRleBitmap(const PegPoint Where, const PegRect &View,
                                   const PegBitmap *pGetmap);

        virtual void DrawTextView(PegPoint Where, const PEGCHAR *pText,
                                  PegBrush &Brush, const PegFont *pFont,
                                  PEGINT Count, PegRect &Rect);

        virtual PEGUBYTE *GetVideoAddress(void);
        virtual void HorizontalLine(PEGINT XStart, PEGINT XEnd, PEGINT YPos,
                                    PEGCOLOR Color, PEGINT Width);
        virtual void HorizontalLineXOR(PEGINT XStart, PEGINT XEnd,
                                       PEGINT YPos);
        virtual void LineView(PEGINT xStart, PEGINT yStart, PEGINT xEnd,
                              PEGINT yEnd, PegRect &Rect, PegBrush &Brush);

        void MakeAAColors(PEGCOLOR *PutColors, PegBrush &Brush);

        void PlotSubPixel(PegFixed xVal, PegFixed yVal,
            PEGCOLOR Color);

        virtual void RectMoveView(const PegRect &View,
                                  const PEGINT xMove, const PEGINT yMove);

       #ifdef PEG_PRO
        PEGCOLOR TrueAlias(PEGCOLOR Back, PEGCOLOR Fore, PEGINT Blend);

       #ifdef PEG_AA_LINE
        virtual void TrueAliasLineView(PEGINT xStart, PEGINT yStart, PEGINT xEnd,
                                PEGINT yEnd, const PegRect &View,
                                PegBrush &Brush);
       #endif
       #endif // PEG_PRO

        virtual void VerticalLine(PEGINT YStart, PEGINT YEnd, PEGINT XPos,
                                  PEGCOLOR Color, PEGINT Width);
        virtual void VerticalLineXOR(PEGINT YStart, PEGINT YEnd, PEGINT XPos);

        PEGCOLOR mHiPalette[256];

};

#endif



